import React, { useState } from 'react';
import Web3 from 'web3';
import styles from './components.module.less';
import { Button, Input, Typography } from 'antd';
import { observer } from 'mobx-react-lite';

interface TokenBalanceProps {
  web3: Web3 | null;
  account: string;
  isConnected: boolean;
  onResult: (result: string) => void;
}

// ERC20代币的标准ABI
const ERC20_ABI = [
  {
    "constant": true,
    "inputs": [{"name":"_owner", "type":"address"}],
    "name": "balanceOf",
    "outputs": [{"name":"balance", "type":"uint256"}],
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [],
    "name": "decimals",
    "outputs": [{"name":"", "type":"uint8"}],
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [],
    "name": "symbol",
    "outputs": [{"name":"", "type":"string"}],
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [],
    "name": "name",
    "outputs": [{"name":"", "type":"string"}],
    "type": "function"
  }
];

const TokenBalance = observer(({ web3, account, isConnected, onResult }: TokenBalanceProps) => {
  const [tokenAddress, setTokenAddress] = useState<string>('');
  const [tokenInfo, setTokenInfo] = useState<{name: string, symbol: string, decimals: number} | null>(null);
  const [tokenBalance, setTokenBalance] = useState<string>('0');
  const [recentTokens, setRecentTokens] = useState<Array<{address: string, name: string, symbol: string}>>([]);

  // 预定义的一些常见代币地址（以太坊主网）
  const popularTokens = [
    { address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', name: 'Dai Stablecoin', symbol: 'DAI' },
    { address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', name: 'USD Coin', symbol: 'USDC' },
    { address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', name: 'Tether USD', symbol: 'USDT' },
    { address: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984', name: 'Uniswap', symbol: 'UNI' },
    { address: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9', name: 'Aave', symbol: 'AAVE' }
  ];

  // 查询代币余额
  const getTokenBalance = async () => {
    if (!web3 || !account || !tokenAddress || !isConnected) {
      alert('请确保已连接钱包并输入代币地址');
      return;
    }

    try {
      onResult('正在查询代币余额...');
      
      // 创建ERC20代币合约实例
      const tokenContract = new web3.eth.Contract(ERC20_ABI, tokenAddress);
      
      // 获取代币信息并确保类型正确
      const name = String(await tokenContract.methods.name().call());
      const symbol = String(await tokenContract.methods.symbol().call());
      const decimals = Number(await tokenContract.methods.decimals().call());
      
      // 获取代币余额并格式化
      const balance = await tokenContract.methods.balanceOf(account).call();
      const formattedBalance = (Number(balance) / Math.pow(10, decimals)).toFixed(decimals > 6 ? 6 : decimals);
      
      setTokenInfo({ name, symbol, decimals });
      setTokenBalance(formattedBalance);
      
      onResult(`成功获取${name}(${symbol})余额: ${formattedBalance}`);
      console.log(`成功获取${name}(${symbol})余额: ${formattedBalance}`);
      
      // 保存到最近查询的代币列表
      saveToRecentTokens({ address: tokenAddress, name, symbol });
    } catch (error) {
      console.error('查询代币余额失败:', error);
      onResult('查询代币余额失败: ' + (error as Error).message);
      // 清除之前的代币信息
      setTokenInfo(null);
      setTokenBalance('0');
    }
  };

  // 保存到最近查询的代币列表
  const saveToRecentTokens = (token: {address: string, name: string, symbol: string}) => {
    setRecentTokens(prev => {
      // 检查是否已存在
      const exists = prev.some(t => t.address.toLowerCase() === token.address.toLowerCase());
      if (exists) {
        return prev;
      }
      
      // 添加新代币到列表开头，并保持最多5个
      const newList = [token, ...prev].slice(0, 5);
      return newList;
    });
  };

  // 从热门代币列表中选择
  const selectPopularToken = (token: {address: string, name: string, symbol: string}) => {
    setTokenAddress(token.address);
    // 注意：从预定义列表选择时，我们还不知道decimals值，需要在查询时获取
    setTokenInfo(null);
    // 自动触发查询
    setTimeout(getTokenBalance, 100);
  };

  // 从最近查询的列表中选择
  const selectRecentToken = (token: {address: string, name: string, symbol: string}) => {
    setTokenAddress(token.address);
    // 注意：从最近查询列表选择时，我们还不知道decimals值，需要在查询时获取
    setTokenInfo(null);
    // 自动触发查询
    setTimeout(getTokenBalance, 100);
  };

  const isUsingPublicNode = account === '使用公共节点连接';

  return (
    <div className={styles.tokenBalance}>
      <Typography.Title level={4}>ERC20代币余额查询</Typography.Title>
      
      <div className={styles.inputGroup}>
        <label>代币地址:</label>
        <Input
          value={tokenAddress}
          onChange={(e) => setTokenAddress(e.target.value)}
          placeholder="0x..."
        />
      </div>
      
      <Button
        type="primary"
        onClick={getTokenBalance}
        className={styles.actionButton}
        disabled={!web3 || !isConnected || !tokenAddress || !account || isUsingPublicNode}
      >查询余额</Button>
      
      {tokenInfo && tokenBalance && (
        <div className={styles.tokenInfo}>
          <Typography.Paragraph><strong>代币名称:</strong> {tokenInfo.name}</Typography.Paragraph>
          <Typography.Paragraph><strong>代币符号:</strong> {tokenInfo.symbol}</Typography.Paragraph>
          <Typography.Paragraph><strong>代币余额:</strong> {tokenBalance}</Typography.Paragraph>
          <Typography.Paragraph><strong>小数点位数:</strong> {tokenInfo.decimals}</Typography.Paragraph>
        </div>
      )}
      
      <div className={styles.tokenLists}>
        {popularTokens.length > 0 && (
          <div className={styles.tokenList}>
            <h4>热门代币</h4>
            <div className={styles.tokenButtons}>
              {popularTokens.map((token, index) => (
                <Button
                  key={index}
                  className={styles.tokenButton}
                  onClick={() => selectPopularToken(token)}
                  title={token.name}
                >
                  {token.symbol}
                </Button>
              ))}
            </div>
          </div>
        )}
        
        {recentTokens.length > 0 && (
          <div className={styles.tokenList}>
            <h4>最近查询</h4>
            <div className={styles.tokenButtons}>
              {recentTokens.map((token, index) => (
                <Button
                  key={index}
                  className={styles.tokenButton}
                  onClick={() => selectRecentToken(token)}
                  title={token.name}
                >
                  {token.symbol}
                </Button>
              ))}
            </div>
          </div>
        )}
      </div>
      
      {isUsingPublicNode && (
        <Typography.Paragraph className={styles.note}>提示: 查询代币余额需要连接MetaMask钱包</Typography.Paragraph>
      )}
    </div>
  );
});

export default TokenBalance;
